﻿//===================================================================================
// Copyright (c) Ryan Garrett.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===================================================================================

using Caffeine.Core.Test.TestModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace Caffeine.Core.Test
{
    [TestClass]
    public class ModelCommandTester
    {
        [TestMethod]
        public void CanExecuteTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            Assert.IsNull(viewModel.CommandExceptionHandler);

            Assert.IsNotNull(viewModel.StringCommand);
            Assert.IsNotNull(viewModel.ObjectCommand);
            Assert.IsNotNull(viewModel.Int32Command);
            Assert.IsNotNull(viewModel.CharCommand);
            Assert.IsNotNull(viewModel.NullableInt32Command);
            Assert.IsNotNull(viewModel.NullableCharCommand);
            Assert.IsNotNull(viewModel.StringArrayCommand);
            Assert.IsNotNull(viewModel.CharArrayCommand);
            Assert.IsNotNull(viewModel.NullableInt32ArrayCommand);
            Assert.IsNotNull(viewModel.StructCommand);

            Assert.IsNull(viewModel.StringCommand.CanExecuteResultOverrideForNulls);
            Assert.IsNull(viewModel.ObjectCommand.CanExecuteResultOverrideForNulls);
            Assert.IsFalse(viewModel.Int32Command.CanExecuteResultOverrideForNulls.Value);
            Assert.IsFalse(viewModel.CharCommand.CanExecuteResultOverrideForNulls.Value);
            Assert.IsNull(viewModel.NullableInt32Command.CanExecuteResultOverrideForNulls);
            Assert.IsNull(viewModel.NullableCharCommand.CanExecuteResultOverrideForNulls);
            Assert.IsNull(viewModel.StringArrayCommand.CanExecuteResultOverrideForNulls);
            Assert.IsNull(viewModel.CharArrayCommand.CanExecuteResultOverrideForNulls);
            Assert.IsNull(viewModel.NullableInt32ArrayCommand.CanExecuteResultOverrideForNulls);
            Assert.IsFalse(viewModel.StructCommand.CanExecuteResultOverrideForNulls.Value);

            Assert.AreEqual(viewModel.StringCommand.ExecuteAction, viewModel.OnStringCommand);
            Assert.AreEqual(viewModel.StringCommand.CanExecutePredicate, ModelBase.CommandDefaultCanExecuteCheck<String>);
            Assert.AreEqual(viewModel.ObjectCommand.ExecuteAction, viewModel.OnObjectCommand);
            Assert.AreEqual(viewModel.ObjectCommand.CanExecutePredicate, viewModel.CanObjectCommandExecute);
            Assert.AreEqual(viewModel.Int32Command.CanExecutePredicate, ModelBase.CommandDefaultCanExecuteCheck<Int32>);
            Assert.AreEqual(viewModel.NullableInt32Command.CanExecutePredicate, ModelBase.CommandDefaultCanExecuteCheck<Nullable<Int32>>);
            Assert.AreEqual(viewModel.StringArrayCommand.CanExecutePredicate, ModelBase.CommandDefaultCanExecuteCheck<String[]>);
            Assert.AreEqual(viewModel.StructCommand.CanExecutePredicate, ModelBase.CommandDefaultCanExecuteCheck<TestStruct>);

            Assert.AreEqual(viewModel, viewModel.StringCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.ObjectCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.Int32Command.Parent);
            Assert.AreEqual(viewModel, viewModel.CharCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.NullableInt32Command.Parent);
            Assert.AreEqual(viewModel, viewModel.NullableCharCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.StringArrayCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.CharArrayCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.NullableInt32ArrayCommand.Parent);
            Assert.AreEqual(viewModel, viewModel.StructCommand.Parent);

            Assert.IsTrue(viewModel.StringCommand.CanExecute(null));
            Assert.IsTrue(viewModel.StringCommand.CanExecute(String.Empty));
            Assert.IsTrue(viewModel.StringCommand.CanExecute("Hello"));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object()));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object[] { }));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(43));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute("SomeValue"));
            Assert.IsFalse(viewModel.Int32Command.CanExecute(null));
            Assert.IsTrue(viewModel.Int32Command.CanExecute(0));
            Assert.IsTrue(viewModel.Int32Command.CanExecute(-34));
            Assert.IsTrue(viewModel.Int32Command.CanExecute(12));
            Assert.IsFalse(viewModel.CharCommand.CanExecute(null));
            Assert.IsFalse(viewModel.CharCommand.CanExecute('A'));
            Assert.IsFalse(viewModel.CharCommand.CanExecute('B'));
            Assert.IsFalse(viewModel.CharCommand.CanExecute('C'));
            Assert.IsTrue(viewModel.NullableInt32Command.CanExecute(null));
            Assert.IsTrue(viewModel.NullableInt32Command.CanExecute(1));
            Assert.IsTrue(viewModel.NullableInt32Command.CanExecute(-1));
            Assert.IsFalse(viewModel.NullableCharCommand.CanExecute(null));
            Assert.IsFalse(viewModel.NullableCharCommand.CanExecute('A'));
            Assert.IsFalse(viewModel.NullableCharCommand.CanExecute('B'));
            Assert.IsTrue(viewModel.StringArrayCommand.CanExecute(null));
            Assert.IsTrue(viewModel.StringArrayCommand.CanExecute(new String[] { }));
            Assert.IsTrue(viewModel.StringArrayCommand.CanExecute(new String[] { "Value" }));
            Assert.IsTrue(viewModel.CharArrayCommand.CanExecute(null));
            Assert.IsTrue(viewModel.CharArrayCommand.CanExecute(new Char[] { }));
            Assert.IsTrue(viewModel.CharArrayCommand.CanExecute(new Char[] { 'A' }));
            Assert.IsTrue(viewModel.NullableInt32ArrayCommand.CanExecute(null));
            Assert.IsTrue(viewModel.NullableInt32ArrayCommand.CanExecute(new Nullable<Int32>[] { }));
            Assert.IsTrue(viewModel.NullableInt32ArrayCommand.CanExecute(new Nullable<Int32>[] { 9 }));
            Assert.IsFalse(viewModel.StructCommand.CanExecute(null));
            Assert.IsTrue(viewModel.StructCommand.CanExecute(new TestStruct()));

            viewModel.StringCommand.Execute(null);
            viewModel.StringCommand.Execute(String.Empty);
            viewModel.StringCommand.Execute("Hello");
            viewModel.ObjectCommand.Execute(null);
            viewModel.ObjectCommand.Execute(new Object());
            viewModel.ObjectCommand.Execute(new Object[] { });
            viewModel.ObjectCommand.Execute(43);
            viewModel.ObjectCommand.Execute("SomeValue");
            viewModel.Int32Command.Execute(0);
            viewModel.Int32Command.Execute(-34);
            viewModel.Int32Command.Execute(12);
            viewModel.CharCommand.Execute('A');
            viewModel.CharCommand.Execute('B');
            viewModel.CharCommand.Execute('C');
            viewModel.NullableInt32Command.Execute(null);
            viewModel.NullableInt32Command.Execute(1);
            viewModel.NullableInt32Command.Execute(-1);
            viewModel.NullableCharCommand.Execute(null);
            viewModel.NullableCharCommand.Execute('A');
            viewModel.NullableCharCommand.Execute('B');
            viewModel.StringArrayCommand.Execute(null);
            viewModel.StringArrayCommand.Execute(new String[] { });
            viewModel.StringArrayCommand.Execute(new String[] { "Value" });
            viewModel.CharArrayCommand.Execute(null);
            viewModel.CharArrayCommand.Execute(new Char[] { });
            viewModel.CharArrayCommand.Execute(new Char[] { 'A' });
            viewModel.NullableInt32ArrayCommand.Execute(null);
            viewModel.NullableInt32ArrayCommand.Execute(new Nullable<Int32>[] { });
            viewModel.NullableInt32ArrayCommand.Execute(new Nullable<Int32>[] { 9 });
            viewModel.StructCommand.Execute(new TestStruct());
        }

        [TestMethod]
        public void CanExecuteCommandTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            List<String> propertyChanges = new List<String>();

            viewModel.ObjectCommand.PropertyChanged += delegate(Object sender, PropertyChangedEventArgs e)
            {
                propertyChanges.Add(e.PropertyName);    
            };

            Assert.IsFalse(viewModel.ObjectCommand.CanExecuteResult);
            Assert.AreEqual(propertyChanges.Count, 0);
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecuteResult);
            Assert.IsNotNull(propertyChanges.Single(p => p == "CanExecuteResult"));
            propertyChanges.Clear();

            viewModel.ObjectCommandCanExecute = false;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecuteResult);
            viewModel.ObjectCommand.CanExecute(null);
            Assert.IsFalse(viewModel.ObjectCommand.CanExecuteResult);
            viewModel.ObjectCommand.CanExecute(null);
            Assert.IsFalse(viewModel.ObjectCommand.CanExecuteResult);
            Assert.IsNotNull(propertyChanges.Single(p => p == "CanExecuteResult"));
            propertyChanges.Clear();
            
            viewModel.ObjectCommandCanExecute = true;
            Assert.IsFalse(viewModel.ObjectCommand.CanExecuteResult);
            viewModel.ObjectCommand.CanExecute(null);
            Assert.IsTrue(viewModel.ObjectCommand.CanExecuteResult);
            viewModel.ObjectCommand.CanExecute(null);
            Assert.IsTrue(viewModel.ObjectCommand.CanExecuteResult);
            Assert.IsNotNull(propertyChanges.Single(p => p == "CanExecuteResult"));
            propertyChanges.Clear();
        }

        [TestMethod]
        public void RaiseCanExecuteChangedTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            Int32 canExecuteChangedCount = 0;

            viewModel.ObjectCommand.RaiseCanExecuteChanged();

            viewModel.ObjectCommand.CanExecuteChanged += delegate(Object sender, EventArgs e)
            {
                Assert.AreEqual(sender, viewModel.ObjectCommand);
                canExecuteChangedCount++;
            };

            viewModel.ObjectCommand.RaiseCanExecuteChanged();
            Assert.AreEqual(canExecuteChangedCount, 1);
            viewModel.ObjectCommand.RaiseCanExecuteChanged();
            Assert.AreEqual(canExecuteChangedCount, 2);
            viewModel.ObjectCommand.RaiseCanExecuteChanged();
            Assert.AreEqual(canExecuteChangedCount, 3);
        }

        [TestMethod]
        public void ReleaseObserversTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            Int32 canExecuteChangeEventCount = 0;

            viewModel.ObjectCommand.CanExecuteChanged += delegate(Object sender, EventArgs e)
            {
                canExecuteChangeEventCount++;
            };

            Int32 propertyChangeEventCount = 0;

            viewModel.ObjectCommand.PropertyChanged += delegate(Object sender, PropertyChangedEventArgs args)
            {
                propertyChangeEventCount++;
            };

            viewModel.ObjectCommand.RaiseCanExecuteChanged();
            viewModel.ObjectCommand.CanExecute(null);

            Assert.AreEqual(canExecuteChangeEventCount, 1);
            Assert.AreEqual(propertyChangeEventCount, 1);

            canExecuteChangeEventCount = 0;
            propertyChangeEventCount = 0;

            viewModel.ObjectCommand.ReleaseObservers();
            viewModel.ObjectCommand.RaiseCanExecuteChanged();
            viewModel.ObjectCommand.CanExecute(null);

            Assert.AreEqual(canExecuteChangeEventCount, 0);
            Assert.AreEqual(propertyChangeEventCount, 0);
        }

        [TestMethod]
        public void CanExecuteResultOverrideTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();

            List<String> propertyChangeEvents = new List<String>();
            viewModel.ObjectCommand.PropertyChanged += delegate(Object sender, PropertyChangedEventArgs args)
            {
                propertyChangeEvents.Add(args.PropertyName);
            };

            Assert.IsNull(viewModel.ObjectCommand.CanExecuteResultOverride);

            viewModel.ObjectCommand.CanExecuteResultOverride = true;
            viewModel.ObjectCommandCanExecute = false;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecuteResult);
            Assert.IsNotNull(propertyChangeEvents.Single(p => p == "CanExecuteResultOverride"));
            propertyChangeEvents.Clear();

            viewModel.ObjectCommand.CanExecuteResultOverride = false;
            viewModel.ObjectCommandCanExecute = true;
            Assert.IsFalse(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsFalse(viewModel.ObjectCommand.CanExecuteResult);
            Assert.IsNotNull(propertyChangeEvents.Single(p => p == "CanExecuteResultOverride"));
            propertyChangeEvents.Clear();

            viewModel.ObjectCommand.CanExecuteResultOverride = false;
            Assert.AreEqual(propertyChangeEvents.Count, 0);

            viewModel.ObjectCommand.CanExecuteResultOverride = null;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecuteResult);
            Assert.IsNotNull(propertyChangeEvents.Single(p => p == "CanExecuteResultOverride"));
            propertyChangeEvents.Clear();
        }

        [TestMethod]
        public void CanExecuteResultOverrideForNullsTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            List<String> propertyChanges = new List<String>();

            viewModel.Int32Command.PropertyChanged += delegate(Object sender, PropertyChangedEventArgs e)
            {
                propertyChanges.Add(e.PropertyName);
            };

            Assert.IsFalse(viewModel.Int32Command.CanExecute(null));
            viewModel.Int32Command.CanExecuteResultOverrideForNulls = false;
            Assert.IsFalse(viewModel.Int32Command.CanExecute(null));
            Assert.IsTrue(viewModel.Int32Command.CanExecute(5));
            Assert.IsNull(propertyChanges.SingleOrDefault(p => p == "CanExecuteResultOverrideForNulls"));
            propertyChanges.Clear();

            viewModel.Int32Command.CanExecuteResultOverrideForNulls = true;
            Assert.IsTrue(viewModel.Int32Command.CanExecute(null));
            Assert.IsTrue(viewModel.Int32Command.CanExecute(-5));
            Assert.IsNotNull(propertyChanges.Single(p => p == "CanExecuteResultOverrideForNulls"));
            propertyChanges.Clear();

            viewModel.Int32Command.CanExecuteResultOverrideForNulls = null;
            Assert.IsTrue(viewModel.Int32Command.CanExecute(0));
            Assert.IsNotNull(propertyChanges.Single(p => p == "CanExecuteResultOverrideForNulls"));
            propertyChanges.Clear();
            viewModel.Int32Command.CanExecuteResultOverrideForNulls = null;
            Assert.AreEqual(propertyChanges.Count, 0);

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = true;
            viewModel.ObjectCommandCanExecute = false;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsFalse(viewModel.ObjectCommand.CanExecute(new Object()));

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = false;
            viewModel.ObjectCommandCanExecute = true;
            Assert.IsFalse(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object()));

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = null;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object()));

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = true;
            viewModel.ObjectCommand.CanExecuteResultOverride = false;
            Assert.IsFalse(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsFalse(viewModel.ObjectCommand.CanExecute(new Object()));

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = false;
            viewModel.ObjectCommand.CanExecuteResultOverride = true;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object()));

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = false;
            viewModel.ObjectCommand.CanExecuteResultOverride = null;
            Assert.IsFalse(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object()));

            viewModel.ObjectCommand.CanExecuteResultOverrideForNulls = null;
            viewModel.ObjectCommand.CanExecuteResultOverride = null;
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(null));
            Assert.IsTrue(viewModel.ObjectCommand.CanExecute(new Object()));
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void CanExecuteWithWrongParameter1()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.NullableCharCommand.CanExecute(4);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void CanExecuteWithWrongParameter2()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.Int32Command.CanExecute("Hello");
        }

        [TestMethod]
        [ExpectedException(typeof(NullReferenceException))]
        public void CanExecuteWithWrongParameter3()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.Int32Command.CanExecuteResultOverrideForNulls = null;
            viewModel.Int32Command.CanExecute(null);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void CanExecuteWithWrongParameter4()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.NullableInt32ArrayCommand.CanExecute("Aloha!!");
        }

        [TestMethod]
        public void CanExecuteWithWrongParameter5()
        {
            IModelFactory factory = new ModelFactory();
            CommandExceptionHandler exceptionHandler = new CommandExceptionHandler();
            factory.CommandExceptionHandler = exceptionHandler;
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            Assert.AreEqual(viewModel.CommandExceptionHandler, exceptionHandler);
            viewModel.NullableInt32ArrayCommand.CanExecute("Aloha!!");
            Assert.IsNotNull(exceptionHandler.CanExecuteException);
            Assert.AreEqual(exceptionHandler.CanExecuteException.GetType(), typeof(InvalidCastException));
            Assert.IsNull(exceptionHandler.ExecuteException);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void ExecuteWithWrongParameter1()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.Int32Command.Execute("Hello");
        }

        [TestMethod]
        [ExpectedException(typeof(NullReferenceException))]
        public void ExecuteWithWrongParameter2()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.CharCommand.Execute(null);
        }

        [TestMethod]
        [ExpectedException(typeof(NullReferenceException))]
        public void ExecuteWithWrongParameter3()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.Int32Command.Execute(null);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidCastException))]
        public void ExecuteWithWrongParameter4()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            viewModel.StringArrayCommand.Execute(new Object[] { });
        }

        [TestMethod]
        public void ExecuteWithWrongParameter5()
        {
            IModelFactory factory = new ModelFactory();
            CommandExceptionHandler exceptionHandler = new CommandExceptionHandler();
            factory.CommandExceptionHandler = exceptionHandler;
            ModelForCommandRegistrationTest viewModel = factory.CreateModel<ModelForCommandRegistrationTest>();
            Assert.AreEqual(viewModel.CommandExceptionHandler, exceptionHandler);
            viewModel.StringArrayCommand.Execute(new Object[] { });
            Assert.IsNull(exceptionHandler.CanExecuteException);
            Assert.IsNotNull(exceptionHandler.ExecuteException);
            Assert.AreEqual(exceptionHandler.ExecuteException.GetType(), typeof(InvalidCastException));
        }

        [TestMethod]
        [ExpectedException(typeof(TargetInvocationException))]
        public void InvalidCommandRegistrationTest1()
        {
            IModelFactory factory = new ModelFactory();
            factory.CreateModel<ModelForIncorrectCommandTestA>();
        }

        [TestMethod]
        [ExpectedException(typeof(TargetInvocationException))]
        public void InvalidCommandRegistrationTest2()
        {
            IModelFactory factory = new ModelFactory();
            factory.CreateModel<ModelForIncorrectCommandTestA>();
        }

        [TestMethod]
        [ExpectedException(typeof(TargetInvocationException))]
        public void InvalidCommandRegistrationTest3()
        {
            IModelFactory factory = new ModelFactory();
            factory.CreateModel<ModelForIncorrectCommandTestB>();
        }

        [TestMethod]
        [ExpectedException(typeof(TargetInvocationException))]
        public void InvalidCommandRegistrationTest4()
        {
            IModelFactory factory = new ModelFactory();
            factory.CreateModel<ModelForIncorrectCommandTestC>();
        }

        [TestMethod]
        [ExpectedException(typeof(TargetInvocationException))]
        public void InvalidCommandRegistrationTest5()
        {
            IModelFactory factory = new ModelFactory();
            factory.CreateModel<ModelForIncorrectCommandTestD>();
        }

        [TestMethod]
        public void AutoRegisterCommandTest()
        {
            IModelFactory factory = new ModelFactory();
            ModelForCommandAutoRegisterTestingB viewModel = factory.CreateModel<ModelForCommandAutoRegisterTestingB>();
            Assert.IsNotNull(viewModel.DoSomethingACommand);
            Assert.AreEqual(viewModel.DoSomethingACommand.CanExecutePredicate, viewModel.OnCanDoSomethingAQuery);
            Assert.AreEqual(viewModel.DoSomethingACommand.ExecuteAction, viewModel.OnDoSomethingAExecute);
            Assert.AreEqual(viewModel.DoSomethingACommand.Parent, viewModel);
            Assert.IsNotNull(viewModel.DoSomethingBCommand);
            Assert.AreEqual(viewModel.DoSomethingBCommand.CanExecutePredicate, viewModel.OnCanDoSomethingBQuery);
            Assert.AreEqual(viewModel.DoSomethingBCommand.ExecuteAction, viewModel.OnDoSomethingBExecute);
            Assert.AreEqual(viewModel.DoSomethingBCommand.Parent, viewModel);
            Assert.IsNotNull(viewModel.DoSomethingCCommand);
            Assert.AreEqual(viewModel.DoSomethingCCommand.CanExecutePredicate, viewModel.OnCanDoSomethingCQuery);
            Assert.AreEqual(viewModel.DoSomethingCCommand.ExecuteAction, viewModel.OnDoSomethingCExecute);
            Assert.AreEqual(viewModel.DoSomethingCCommand.Parent, viewModel);
            Assert.IsNotNull(viewModel.DoSomethingDCommand);
            Assert.AreEqual(viewModel.DoSomethingDCommand.CanExecutePredicate, viewModel.OnCanDoSomethingDQuery);
            Assert.AreEqual(viewModel.DoSomethingDCommand.ExecuteAction, viewModel.OnDoSomethingDExecute);
            Assert.AreEqual(viewModel.DoSomethingDCommand.Parent, viewModel);
            Assert.IsNotNull(viewModel.DoSomethingECommand);
            Assert.AreEqual(viewModel.DoSomethingECommand.CanExecutePredicate, viewModel.OnCanDoSomethingEQuery);
            Assert.AreEqual(viewModel.DoSomethingECommand.ExecuteAction, viewModel.OnDoSomethingEExecute);
            Assert.AreEqual(viewModel.DoSomethingECommand.Parent, viewModel);
            Assert.IsNotNull(viewModel.DoSomethingFCommand);
            Assert.AreEqual(viewModel.DoSomethingFCommand.CanExecutePredicate, viewModel.OnCanDoSomethingFQuery);
            Assert.AreEqual(viewModel.DoSomethingFCommand.ExecuteAction, viewModel.OnDoSomethingFExecute);
            Assert.AreEqual(viewModel.DoSomethingFCommand.Parent, viewModel);
        }
    }
}
